package dispatcher.gui.state;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.ArrayList;

import state.Globals;
import state.group.HallCall;
import state.group.events.EventCollection;
import state.person.Person;
import state.person.PersonDispatcherState;
import state.person.events.PersonRegisterEvent;

import dispatcher.person.gui.state.PersonDataCollection;

public class PersonDispatcherStateHandler extends StateHandler {

	private static final PersonDispatcherStateHandler instance = new PersonDispatcherStateHandler();
	
	/**
	 * Returns an instance of the person dispatcher state
	 */
	public static PersonDispatcherStateHandler getInstance(){
		return instance;
	}
	
	private PersonDataCollection personCollection;
	
	@SuppressWarnings("unused")
	private PersonDispatcherState personDispatcherState;
	
	/**
	 * The main constructor
	 */
	private PersonDispatcherStateHandler(){
		personCollection = new PersonDataCollection();
	}	
	
	/**
	 * This will update the local copy with a list of events
	 */
	@Override
	public void updateEvents(EventCollection collection) {
		Globals.getLogger().log("The number of person events are " + collection.size(), this.getClass().getName(), "updateEvents");
		synchronized(this){
			this.personCollection.updateStructUsingEvents(collection);
		}
		// Notifies all listeners that an elevator event has occured
		for(ActionListener l : listener){
			l.actionPerformed(new ActionEvent(this, 0, ""));
		}
	}
	
	/**
	 * This method will initialize the person dispatcher state
	 * @param state The state of the person dispatcher
	 */
	public void createInitialStatus(PersonDispatcherState state){
		synchronized(this){
			this.personCollection.clear();
			this.personDispatcherState = state;
			
			createPersonInitialState(state.activePeople);
		}
		
		// Notify all the action listeners that the state has been initialized
		for(ActionListener l : listener){
			l.actionPerformed(new ActionEvent(this, 0, ""));
		}
	}
	
	/**
	 * This method will initialise the local copy of the person dispatcher
	 * @param person The list of people in the system
	 */
	private synchronized void createPersonInitialState(ArrayList<Person> person){
		EventCollection collection = new EventCollection();
		for(Person p : person){
			synchronized(p){
				HallCall newCall = null;
				synchronized(p.getHallCall()){
					newCall = new HallCall(p.getHallCall().getFloor(), p.getHallCall().getDirection());
				}
				Person newPerson = new Person(p.getName(), p.getType(), p.getWeight(), newCall, (byte)p.getDestination());
				collection.add(new PersonRegisterEvent(newPerson));
			}
		}
		this.personCollection.updateStructUsingEvents(collection);
	
	}
	
	/**
	 * This method will return a person with the same name
	 * @param name The name of the person
	 * @return Returns the person associated with the same name
	 */
	public synchronized Person getPersonStatus(String name){
		return personCollection.get(name);
	}

	public synchronized String getPersonCollectionInfo(){
		return personCollection.getPersonCollectionInfo();
	}
	
	public synchronized void resetPeople(){
		personCollection.clear();
		personCollection.resetTextCollection();
	}
}
